package com.atguigu.spring.aop.annotation;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

import java.util.Arrays;

/**
 * @author wk
 * @create 2021-06-02 20:38
 */
@Component
// 使用@Aspect标识这是一个切面组件
@Aspect
public class LoggerAspect {

    // 抽取公用的切入点表达式
    @Pointcut("execution(* com.atguigu.spring.aop.annotation.*.*(..))")
    public void pointCut(){

    }
    // 切入点表达式 第一个*表示任意的返回值类型，第二个*表示包下任意的类，第三个*表示类中任意的方法，..表示任意的参数列表
    //@Before("execution(* com.atguigu.spring.aop.com.atguigu.spring.tx.annotation.*.*(..))")
    //@Before("execution(int com.atguigu.spring.aop.com.atguigu.spring.tx.annotation.CaculatorImpl.*(int,int))")
    // 调用抽取的切入点表达式
    //@Before("pointCut()")
    public void beforeMethod(JoinPoint joinPoint){
        //JoinPoint表示当前通知作用于的连接点，可以通过此对象获取连接点相关信息，例如方法名、参数
        System.out.println("Logger-->前置通知，方法名："+joinPoint.getSignature().getName()+"，参数："+ Arrays.toString(joinPoint.getArgs()));
    }

    //@After("pointCut()")
    public void afterMethod(JoinPoint joinPoint){
        System.out.println("Logger-->后置通知，方法名："+joinPoint.getSignature().getName()+",参数"+Arrays.toString(joinPoint.getArgs()));
    }
    //@AfterReturning(value = "pointCut()",returning = "result")
    public void afterReturningMethod(JoinPoint joinPoint,Object result){
        System.out.println("Logger-->返回通知，方法名："+joinPoint.getSignature().getName()+",参数"+Arrays.toString(joinPoint.getArgs())+"，返回值"+result);
    }
    //@AfterThrowing(value = "pointCut()",throwing = "ex")
    public void exceptionMethod(JoinPoint joinPoint,Throwable ex){
        System.out.println("Logger-->异常通知，方法名："+joinPoint.getSignature().getName()+",参数"+Arrays.toString(joinPoint.getArgs())+"，返回值"+ex);
    }
    @Around(value = "pointCut()")
    public Object aroundMethod(ProceedingJoinPoint joinPoint){
        Object result=null;
        try {
            System.out.println("前置通知");
            result = joinPoint.proceed();
            System.out.println("返回通知");
        } catch (Throwable throwable) {
            throwable.printStackTrace();
            System.out.println("异常通知");
        }finally {
            System.out.println("后置通知");
        }
        return result;
    }

}
